<template>
  <div class="" :style="{height: $store.state.height + 'px'}" style="width: 100%;position: relative;">
    <div id="draw-baidu-map" :style="{height: $store.state.height + 'px', width: '100%'}"></div>
    <el-select v-model="type" placeholder="请选择" class="darw-type" @change="typeChange" style="width: 100px;">
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value">
      </el-option>
    </el-select>
    <div class="modify-type">
      <label>是否可以修改</label>
      <el-radio v-model="modify" :label="true">是</el-radio>
      <el-radio v-model="modify" :label="false">否</el-radio>
    </div>
    <div class="draw-tools">
      <a @click="clearSource()">Clear</a>
      <a download="features.json" ref="download" @click="download">Download</a>
    </div>
  </div>
</template>

<script>
require('cesium/Source/Widgets/widgets.css');
import Cesium from 'cesium/Source/Cesium';
window.Cesium = Cesium;
import OLCesium from 'ol-cesium/src/olcs/OLCesium.js';

import 'ol/ol.css'
import Map from 'ol/Map'
import View from 'ol/View'
import { Modify, Snap } from 'ol/interaction'
// 绘制矩形，正方形和星形
import Draw, {createRegularPolygon, createBox} from 'ol/interaction/Draw.js';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
import { OSM, Vector as VectorSource } from 'ol/source'
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style'
import Polygon from 'ol/geom/Polygon'
import GeoJSON from 'ol/format/GeoJSON';

const raster = new TileLayer({
  source: new OSM()
})

const source = new VectorSource({wrapX: false})

const vector = new VectorLayer({
  source: source,
  style: new Style({
    fill: new Fill({
      color: 'rgba(255, 255, 255, 0.3)'
    }),
    stroke: new Stroke({
      color: '#7b98bc',
      width: 1
    }),
    image: new CircleStyle({
      radius: 7,
      fill: new Fill({
        color: '#7b98bc'
      })
    })
  })
})

const modify = new Modify({source: source})

const format = new GeoJSON({featureProjection: 'EPSG:3857'});

export default {
  name: "cesiumdraw",
  title: "3D绘制图形",
  data () {
    return {
      modify: false,
      type: '',
      options: [
        {label: '点', value: 'Point'},
        {label: '折线', value: 'LineString'},
        {label: '多边形', value: 'Polygon'},
        {label: '园', value: 'Circle'},
        {label: '矩形', value: 'Box'},
        {label: '正方形', value: 'Square'},
        // {label: '星型', value: 'Star'},
        {label: '不绘制', value: ''}
      ],
      map: {},
      draw: {},
      snap: {},
      geometryFunction: null
    }
  },
  mounted () {
    this.map = new Map({
      target: 'draw-baidu-map',
      layers: [raster, vector],
      view: new View({
        center: [11000000, 4600000],
        zoom: 4
      })
    })
    this.modifyChange()
    this.typeChange()


    let ol3d = new OLCesium({
      map: this.map,
      time() {
        return Cesium.JulianDate.now();
      }
    });
    let scene = ol3d.getCesiumScene();
    scene.terrainProvider = Cesium.createWorldTerrain();
    ol3d.setEnabled(true);
  },
  methods: {
    // 类型发生变化
    typeChange (type) {
      if (type === 'Square') {
        this.geometryFunction = createRegularPolygon(4)
      } else if (type === 'Box') {
        this.geometryFunction = createBox()
      } else if (type === 'Star') {
        // this.geometryFunction = this.drawStar
      } else {
        this.geometryFunction = null
      }
      this.map.removeInteraction(this.draw)
      this.map.removeInteraction(this.snap)
      if (this.type) {
        this.addInteraction()
      }
    },
    modifyChange () {
      if (this.modify) {
        this.map.addInteraction(modify)
      } else {
        this.map.removeInteraction(modify)
      }
    },
    addInteraction () {
      this.draw = new Draw({
        source: source,
        type: this.type === 'Square' || this.type === 'Box' || this.type === 'Star' ? 'Circle' : this.type,
        geometryFunction: this.geometryFunction
      })
      this.map.addInteraction(this.draw)
      this.snap = new Snap({source: source})
      this.map.addInteraction(this.snap)
    },
    // 获取绘制类型，由于矩形和正方形和星形的类型都为Circle
    clearSource () {
      source.clear()
    },
    download () {
      const features = source.getFeatures();
      const json = format.writeFeatures(features);
      this.$refs.download.href = 'data:text/json;charset=utf-8,' + json;
    },
    // 绘制星形函数
    drawStar (coordinates, geometry) {
      if (!geometry) {
        geometry = new Polygon(null)
      }
      let center = coordinates[0]
      let last = coordinates[1]
      let dx = center[0] - last[0]
      let dy = center[1] - last[1]
      let radius = Math.sqrt(dx * dx + dy * dy)
      let rotation = Math.atan2(dy, dx)
      let newCoordinates = []
      let numPoints = 12
      for (let i = 0; i < numPoints; i++) {
        let angle = rotation + i * 2 * Math.PI / numPoints
        let fraction = i % 2 === 0 ? 1 : 0.5
        let offsetX = radius * fraction * Math.cos(angle)
        let offsetY = radius * fraction * Math.sin(angle)
        newCoordinates.push([center[0] + offsetX], center[1] + offsetY)
      }
      newCoordinates.push(newCoordinates[0].slice())
      geometry.setCoordinates([newCoordinates])
      return geometry
    }
  },
  watch: {
    'modify' () {
      this.modifyChange()
    }
  }
}
</script>

<style lang="scss" scoped>
.darw-type {
  position: absolute;
  top: 1rem;
  right: 1rem;
}
.modify-type {
  position: absolute;
  top: 4rem;
  right: 1rem;
}
.draw-tools {
  position: absolute;
  top: 6rem;
  right: 1rem;
  a {
    display: inline-block;
    padding: 0.5rem;
    background: white;
    cursor: pointer;
  }
}

</style>
